/*
 * MIT License
 *
 * Copyright (c) 2023 北京凯特伟业科技有限公司
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package com.je.message.service.portal.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson2.JSONObject;
import com.beust.jcommander.internal.Lists;
import com.je.common.base.DynaBean;
import com.je.common.base.JsonAssist;
import com.je.common.base.constants.push.PushAct;
import com.je.common.base.constants.push.PushType;
import com.je.common.base.mapper.query.NativeQuery;
import com.je.common.base.message.vo.NoticeMsg;
import com.je.common.base.micromail.service.MicromailService;
import com.je.common.base.portal.vo.PushActVo;
import com.je.common.base.result.BaseRespResult;
import com.je.common.base.service.CommonService;
import com.je.common.base.service.MetaResourceService;
import com.je.common.base.service.MetaService;
import com.je.common.base.util.StringUtil;
import com.je.ibatis.extension.conditions.ConditionsWrapper;
import com.je.message.service.portal.PortalService;
import com.je.message.vo.WebPushTypeEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Service
public class PortalServiceImpl implements PortalService {

    @Autowired
    private CommonService commonService;
    @Autowired
    private MetaService metaService;
    @Autowired
    private MicromailService micromailService;
    @Autowired
    private MetaResourceService metaResourceService;

    private final String INSERT = "insert";
    private final String DO_UPDATE = "doUpdate";

    /**
     * 推送指定消息
     *
     * @param userId    用户id
     * @param pushTypes 推送消息类型
     * @param pushActs  TODO 暂不明确
     */
    @Override
    public void push(String userId, String deptId, String[] pushTypes, String[] pushActs) {

        JsonAssist jsonAssist = JsonAssist.getInstance();
        boolean onlyPhone = true;
        for (String pushAct : pushActs) {
            if (!PushAct.BADGE.equals(pushAct)) {
                onlyPhone = false;
            }
        }
//        if (onlyPhone) {//&& !"1".equals(WebUtils.getSysVar("JE_PHONE_APK"))
//            return;
//        }
        List<PushActVo> pushActVos = getPushInfo(userId, pushTypes, pushActs);
        if (pushActVos.size() > 0) {
            if (onlyPhone) {
//                pushService.sendMsgWithCallFunctionAndLogined(userId, deptId,"", jsonAssist.buildListPageJson(new Long(pushActVos.size()), pushActVos, new String[]{}, false), "JE.doPushInfo", "", false);
            }
        }
    }


    @Override
    public List<PushActVo> getPushInfo(String userId, String[] pushTypes, String[] pushActs) {
        List<PushActVo> pushActVos = new ArrayList<>();
        for (int i = 0; i < pushTypes.length; i++) {
            String pushType = pushTypes[i];
            String pushAct = pushActs[i];
            PushActVo pushActVo = new PushActVo();
            pushActVo.setType(pushType);
            if (PushAct.NUM.equals(pushAct)) {
                pushActVo.setNum(true);
            } else if (PushAct.BADGE.equals(pushAct)) {
                pushActVo.setBadge(true);
            } else if (PushAct.REFRESH.equals(pushAct)) {
                pushActVo.setRefresh(true);
            } else if (PushAct.REFRESHNUM.equals(pushAct)) {
                pushActVo.setRefreshNum(true);
            } else if (PushAct.ALL.equals(pushAct)) {
                pushActVo.setNum(true);
                pushActVo.setRefresh(true);
                //前端通过这个来进行判断是否去刷新角标
                pushActVo.setRefreshNum(true);
            }
            //信息类型
            if (pushActVo.getNum()) {
                if (PushType.MSG.equals(pushType)) {
                    pushActVo.setNumObj(getMsgNum(userId));
                } else if (PushType.POSTIL.equals(pushType)) {
                    pushActVo.setNumObj(getPostilNum(userId));
                } else if (PushType.WY.equals(pushType)) {
                    pushActVo.setNumObj(getRzNumWyNum(userId));
                }
            }
            if (PushType.MSG.equals(pushType)) {
                pushActVo.setCode("JE-PLUGIN-IM");
            } else if (PushType.WY.equals(pushType)) {
                pushActVo.setCode("JE-PLUGIN-MICROMAIL");
            } else if (PushType.POSTIL.equals(pushType)) {
                pushActVo.setCode("JE-PLUGIN-ANNOTATION");
            }

            if (pushActVo.getBadge()) {
                if (PushType.MSG.equals(pushType)) {
                    pushActVo.setBadgeObj(getMsgBadge(userId));
                } else if (PushType.POSTIL.equals(pushType)) {
                    pushActVo.setBadgeObj(getPostilBadge(userId));
                } else if (PushType.WY.equals(pushType)) {
                    pushActVo.setBadgeObj(getWyBadge(userId));
                }
            }
            pushActVos.add(pushActVo);
        }
        return pushActVos;
    }

    //微邮未读数
    private JSONObject getRzNumWyNum(String userId) {
        JSONObject numObj = new JSONObject();
        long count = micromailService.getNoReadsCount(userId);
        numObj.put("numCount", count);
        return numObj;
    }

    //微邮角标
    private JSONObject getWyBadge(String userId) {
        JSONObject numObj = new JSONObject();
        long count = micromailService.getNoReadsCount(userId);
        numObj.put("badge", count);
        return numObj;
    }


    /**
     * 获取消息数字
     *
     * @param userId 用户id
     * @return
     */
    private JSONObject getMsgNum(String userId) {
        JSONObject numObj = new JSONObject();
        String excludeTypes = "WF,PZ,POSTIL,BUBBLE,TRANSACTION";
        String baseSql = " AND USERMSG_MSGTYPE_CODE NOT IN (" + StringUtil.buildArrayToString(excludeTypes.split(",")) + ")";
        long msgCount = metaService.countBySql(ConditionsWrapper.builder().table("JE_SYS_USERMSG").apply(" AND USERMSG_JSR_ID='" + userId + "' AND USERMSG_YD='0' " + baseSql));
        numObj.put("msgCount", msgCount);
        return numObj;
    }

    /**
     * 获取消息角标
     *
     * @param userId 用户id
     * @return
     */
    private JSONObject getMsgBadge(String userId) {
        JSONObject numObj = new JSONObject();
        String excludeTypes = "WF,PZ,POSTIL,BUBBLE,TRANSACTION";
        String baseSql = " AND USERMSG_MSGTYPE_CODE NOT IN (" + StringUtil.buildArrayToString(excludeTypes.split(",")) + ")";
        long msgCount = metaService.countBySql(ConditionsWrapper.builder().table("JE_SYS_USERMSG").apply(" AND USERMSG_JSR_ID='" + userId + "' AND USERMSG_YD='0' " + baseSql));
        numObj.put("badge", msgCount);
        return numObj;
    }


    /**
     * 获取批注数字
     *
     * @param userId 用户id
     * @return
     */
    public JSONObject getPostilNum(String userId) {
        JSONObject numObj = new JSONObject();
        StringBuffer whereSql = new StringBuffer();

        List<DynaBean> list = metaResourceService.selectByTableCodeAndNativeQueryWithColumns("JE_CORE_FUNCEDIT", NativeQuery.build().eq("FUNCEDIT_USERID", userId).eq("FUNCEDIT_FUNCCODE", "JE_CORE_POSTIL").eq("FUNCEDIT_NEW", "0"), "FUNCEDIT_PKVALUE");
        List<String> idList = Lists.newArrayList();
        for (DynaBean eachBean : list) {
            idList.add(eachBean.getStr("FUNCEDIT_PKVALUE"));
        }
        whereSql.append(" AND (SY_CREATEUSERID='" + userId + "' OR POSTIL_HFRID='" + userId + "') ");
        whereSql.append(" AND POSTIL_MODELID NOT IN (" + StringUtil.buildArrayToString(idList) + ")");
        String querySql = " SELECT POSTIL_FUNCCODE,POSTIL_TABLECODE,POSTIL_MODELID,COUNT(*) POSTILCOUNT,MAX(SY_CREATETIME) SY_CREATETIME FROM JE_CORE_POSTIL WHERE 1=1 " + whereSql.toString() + " GROUP BY POSTIL_FUNCCODE,POSTIL_TABLECODE,POSTIL_MODELID ";
        Long count = metaService.countBySql(querySql);
        numObj.put("numCount", count);
        return numObj;
    }

    /**
     * 获取批注角标
     *
     * @param userId 用户id
     * @return
     */
    private JSONObject getPostilBadge(String userId) {
        JSONObject numObj = new JSONObject();
        StringBuffer whereSql = new StringBuffer();

        List<DynaBean> list = metaResourceService.selectByTableCodeAndNativeQueryWithColumns("JE_CORE_FUNCEDIT", NativeQuery.build().eq("FUNCEDIT_USERID", userId).eq("FUNCEDIT_FUNCCODE", "JE_CORE_POSTIL").eq("FUNCEDIT_NEW", "0"), "FUNCEDIT_PKVALUE");
        List<String> idList = Lists.newArrayList();
        for (DynaBean eachBean : list) {
            idList.add(eachBean.getStr("FUNCEDIT_PKVALUE"));
        }
        whereSql.append(" AND (SY_CREATEUSERID='" + userId + "' OR POSTIL_HFRID='" + userId + "') ");
        whereSql.append(" AND POSTIL_MODELID NOT IN (" + StringUtil.buildArrayToString(idList) + ")");
        String querySql = " SELECT COUNT(*) FROM JE_CORE_POSTIL WHERE 1=1 " + whereSql.toString() + " GROUP BY POSTIL_FUNCCODE,POSTIL_TABLECODE,POSTIL_MODELID ";
        Long count = metaService.countBySql(querySql);
        numObj.put("badge", count);
        return numObj;
    }


    @Override
    public BaseRespResult insertOrUpdateSign(String userId, String deptId, WebPushTypeEnum pushTypes, String actionType) {
        List<DynaBean> dynaBeanList = metaService.select("JE_MESSAGE_READMARK", ConditionsWrapper.builder().eq("READMARK_XXLX_CODE", pushTypes).eq("READMARK_JSR_ID", userId).eq("READMARK_JSRBM_ID", deptId));
        boolean exist = true;
        DynaBean dynaBean = null;
        if (dynaBeanList == null || dynaBeanList.size() == 0) {
            dynaBean = new DynaBean("JE_MESSAGE_READMARK", true);
            exist = false;
        } else {
            dynaBean = dynaBeanList.get(0);
            for (int i = 1; i < dynaBeanList.size(); i++) {
                metaService.delete(ConditionsWrapper.builder().table("JE_MESSAGE_READMARK").eq("JE_MESSAGE_READMARK_ID", dynaBeanList.get(i).getStr("JE_MESSAGE_READMARK_ID")));
            }
        }
        if (pushTypes.equals(WebPushTypeEnum.MSG)) {
            dynaBean.setStr("READMARK_XXLX_CODE", PushType.MSG);
            dynaBean.setStr("READMARK_XXLX_NAME", PushType.MSG_NAME);
        } else if (pushTypes.equals(WebPushTypeEnum.WF)) {
            dynaBean.setStr("READMARK_XXLX_CODE", PushType.WF);
            dynaBean.setStr("READMARK_XXLX_NAME", PushType.WF_NAME);
        } else {
            return BaseRespResult.errorResult("请确认您选择类型！");
        }
        //1 未读 0 已读
        if (DO_UPDATE.equals(actionType)) {
            dynaBean.setStr("READMARK_SFYD_CODE", "0");
        } else if (INSERT.equals(actionType)) {
            dynaBean.setStr("READMARK_SFYD_CODE", "1");
        }
        dynaBean.setStr("READMARK_JSR_ID", userId);
        dynaBean.setStr("READMARK_JSRBM_ID", deptId);
        if (exist) {
            metaService.update(dynaBean);
        } else {
            commonService.buildModelModifyInfo(dynaBean);
            metaService.insert(dynaBean);
        }
        return BaseRespResult.successResult("设置成功！");
    }

    @Override
    public BaseRespResult loadReadSign(String userId, String deptId, String pushTypes) {

        HashMap<String, Object> map = CollUtil.newHashMap();
        List<DynaBean> dynaBean = metaService.select("JE_MESSAGE_READMARK", ConditionsWrapper.builder().eq("READMARK_JSR_ID", userId).eq("READMARK_JSRBM_ID", deptId).in("READMARK_XXLX_CODE", Stream.of(pushTypes.split(",")).collect(Collectors.toList())));
        if (dynaBean == null || dynaBean.size() == 0) {
            map.put("MSG", "0");
            map.put("WF", "0");
            return BaseRespResult.successResult(map);
        }
        ArrayList<String> list = new ArrayList<>();
        for (DynaBean bean : dynaBean) {
            list.add(bean.getStr("READMARK_XXLX_CODE"));
        }
        for (DynaBean bean : dynaBean) {
            if (!list.contains("MSG")) {
                map.put("MSG", "0");
            }
            if (!list.contains("WF")) {
                map.put("WF", "0");
            }
            map.put(bean.getStr("READMARK_XXLX_CODE"), bean.get("READMARK_SFYD_CODE"));
        }
        return BaseRespResult.successResult(map);
    }

    @Override
    public BaseRespResult insertNoticeMsg(NoticeMsg noticeMsg) {
        if (noticeMsg == null) {
            return null;
        }
        DynaBean dynaBean = new DynaBean("JE_SYS_USERMSG", false);
        dynaBean.setStr("USERMSG_JSR_ID", noticeMsg.getTargetUserId());
        dynaBean.setStr("USERMSG_JSR_NAME", noticeMsg.getTargetUserName());
        dynaBean.setStr("USERMSG_JSRSZBM_ID", noticeMsg.getTargetUserDeptId());
        dynaBean.setStr("USERMSG_JSRSZBM", noticeMsg.getTargetUserDeptName());
        dynaBean.setStr("USERMSG_JSRSZBM", noticeMsg.getTargetUserDeptName());
        dynaBean.setStr("USERMSG_NR", noticeMsg.getContent());
        dynaBean.setStr("USERMSG_BT", noticeMsg.getTitle());
        dynaBean.setStr("USERMSG_YD", "0");
        dynaBean.setStr("USERMSG_JSSJ", DateUtil.now());
        dynaBean.setStr("USERMSG_MSGTYPE_CODE", noticeMsg.getMsgTypeCode());
        dynaBean.setStr("USERMSG_MSGTYPE_NAME", noticeMsg.getMsgTypeName());
        dynaBean.setStr("USERMSG_SHOW_FUNCFORM_INFO", noticeMsg.getShowFuncFormInfo());
        commonService.buildModelCreateInfo(dynaBean);
        metaService.insert(dynaBean);
        return BaseRespResult.successResult(dynaBean);
    }
}
